import * as bodyparser from 'koa-bodyparser'
import router from '../router'
import Config from '../config';
import * as fs from 'fs'
import * as path from 'path'
import { watch, WatchType } from '../utils/file';
import { HttpCode, ctx } from '../utils/iface';
import { RPC as RPCServer } from '../utils/ws';
import * as multiparty from 'koa2-multiparty'
import { session } from './session';
export async function cors(ctx: any | ctx, next: Function) {
    //TODO 动态加载配置文件完成
    if (ctx.method == 'OPTIONS') {
        corsset(ctx)
        ctx.body = "";
    } else if (ctx.method == "POST") {
        if (ctx.config.allowCORS) {
            await next();
            corsset(ctx)
        }
    } else {
        await next();
    }
}
export async function corsset(ctx) {
    ctx.set('Access-Control-Allow-Origin', ctx.header.origin);
    ctx.set("Access-Control-Allow-Headers", "x-requested-with, accept, origin, content-type");
    ctx.set("Access-Control-Allow-Credentials", true);
    ctx.set("Access-Control-Max-Age", 86400);
}
export async function config(ctx, next) {
    let AppConfig;
    try {
        let configPath = path.resolve('dist/config/index.js')
        if (fs.existsSync(configPath)) {
            AppConfig = require(configPath).default;
        }
    } catch (error) {
        console.log(error)
    } finally {
        let c = AppConfig ? AppConfig : Config
        ctx.config = new c(ctx);
        await next();
    }
}
export async function outcheck(ctx: ctx, next) {
    await next();
    if (!ctx.config.sendFile && ctx.control && !(ctx.body instanceof fs.ReadStream)) {
        if (ctx.error && ctx.status == HttpCode.OK) { ctx.status = HttpCode.SERVER_ERROR }
        ctx.body = ctx.config.outformat
    }
}
export default function middlewares(app) {
    app.use(config)
    app.use(cors)
    app.use(bodyparser({
        enableTypes: ['json', 'form', 'text',]
    }))
    app.use(multiparty())
    let configPath = path.resolve('dist/config/index.js')
    watch([configPath, 'dist/controller/*.js', 'dist/db/*.js', 'dist/relation/*.js', 'dist/utils/*.js'], [WatchType.Add, WatchType.Change, WatchType.Delete], (d) => {
        if (require.cache[path.resolve(d)]) {
            console.log(`File ${d} changed,deleted cache`)
            delete require.cache[path.resolve(d)]
        }
    })
    app.use(session)
    app.use(router)
    app.use(outcheck)
    if (app.ws) {
        //启用WebSocket服务
        app.ws.use(config)
        app.ws.use((ctx, next) => {
            // console.log('ClientAmount:' + app.ws.server.clients.size)
            //超时自动关闭
            setTimeout(() => {
                if (!ctx.ID) {
                    // console.log('Close:' + app.ws.server.clients.size)
                    ctx.websocket.close()
                }
            }, 3000)
            ctx.websocket.on('message', async (message: any) => {
                if ('string' == typeof message) {
                    ctx.RPCEncoding = 'text'
                }
                RPCServer.message(message, ctx)
            })
            ctx.websocket.on('close', () => {
                RPCServer.close(ctx)
            })
            next();
        })
    }
}


